package com.zhongwang.business.module.system.login;

import com.zhongwang.business.annotation.LogAnnotation;
import com.zhongwang.business.base.BaseController;
import com.zhongwang.business.common.JsonResult;
import com.zhongwang.business.gen.entity.User;
import com.zhongwang.business.module.system.user.UserService;
import com.zhongwang.business.util.ServletUtils;
import com.zhongwang.business.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 *  登录控制器
 * @author China.sgl
 * @date 2019/9/19 09:41
 */
@Controller
public class LoginController extends BaseController {

    @Autowired
    private UserService userService;

    @Value("${spring.profiles.active}")
    private String profile;

    /**
     * 登录页面
     *
     * @return 页面路径
     */
    @GetMapping("/")
    public String root(Model model, HttpServletRequest request, HttpServletResponse response) {
        // 如果是Ajax请求，返回Json字符串。
        if (ServletUtils.isAjaxRequest(request)) {
            return ServletUtils.renderString(response, "{\"type\":\"ERROR\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }
        model.addAttribute("profile", profile);
        return "login";
    }

    /**
     * 登录
     *
     * @param user 用户
     * @return json
     */
    @ResponseBody
    @PostMapping("/login")
    @LogAnnotation(value = "登录")
    public JsonResult login(User user) {

        JsonResult jsonResult = new JsonResult();
        try {
            User currentUser = userService.findByAccount(user.getAccount());
            if (null == currentUser) {

                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("帐号密码错误");
                return jsonResult;
            }
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getAccount(), user.getPassword());
            Subject subject = SecurityUtils.getSubject();
            subject.login(usernamePasswordToken);
            //检查当前登录用户信息，将存在重复登录用户信息筛选出来
            List<Session> loginedList = getLoginedSession(subject);
            for (Session session : loginedList) {
                session.stop();//关闭重复用户登录信息缓存
            }
            // 保存当前登录用户到 session
            Session session = subject.getSession();
            session.setAttribute("user", currentUser);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            return jsonResult;
        } catch (Exception e) {
            e.printStackTrace();
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("帐号密码错误");
            return jsonResult;
        }
    }



    /**
     *
     * @param currentUser 当前登录用户的shiro认证信息
     * @return 重复登录的用户Session（shiro格式）
     * Description: 遍历同一个账户的现有的session用户信息并将重复的登录缓存信息输出
     * @author 徐一贺
     * @date
     */
    private List<Session> getLoginedSession(Subject currentUser) {
        //获得当前登录用户的全部session
        Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils
                .getSecurityManager()).getSessionManager()).getSessionDAO()
                .getActiveSessions();
        List<Session> loginedList = new ArrayList<Session>();
        User loginUser = (User) currentUser.getPrincipal();//获得当前用户信息
        for (Session session : list) {
            Subject s = new Subject.Builder().session(session).buildSubject();

            if (s.isAuthenticated()) {
                User user = (User) s.getPrincipal();

                if (user.getAccount().equalsIgnoreCase(loginUser.getAccount())) {
                    if (!session.getId().equals(
                            currentUser.getSession().getId())) {
                        loginedList.add(session);//把除当前登录用户的其他的同名用户session信息加入集合
                    }
                }
            }
        }
        return loginedList;
    }

    @ResponseBody
    @PostMapping("/getLoginUserName")
    /**
     *@FunctionName: getLoginUserName
     * 获取登录用户名
     *@DesignIdea: 获取当前登录用户名
     *@author 徐一贺
     *@CreateDate: 2020/5/25 10:24
     *@Phone: 18210416791
     *@param []
     *@return com.zhongwang.business.common.JsonResult
     *@version: v 1.0.0
     */
    public JsonResult getLoginUserName() {
        return JsonResult.success("", ShiroUtils.getUser().getName());
    }


}
